<?php

namespace app\index\service;

use app\common\job\TradeEnd;
use app\common\model\Consulting;
use app\common\model\ConsultingMessage;
use app\common\model\ConsultingReward;
use app\common\model\ConsultingServer;
use app\common\model\Member;
use app\common\model\Trade;
use app\common\service\TemplateSmsService;
use app\index\dao\TradeDao;
use app\index\model\UM as UM;
use app\index\traits\TradeShareEstimateTrait;
use ShidianUtil\Utils\CheckUtil;
use think\exception\ValidateException;
use think\facade\Config;
use think\facade\Queue;

/**
 * Class RewardService
 * @package app\trade\service
 * @deprecated
 */
class TradeRewardService implements TradableInterface
{
    use TradeShareEstimateTrait;

    // dao
    private TradeDao $tradeDao;

    public function __construct(TradeDao $tradeDao)
    {
        $this->tradeDao = $tradeDao;
    }

    /**
     * 新增
     * @param \app\index\model\UM $user
     * @param array $params
     * @return  Trade
     */
    public function add(UM $user, array $params): Trade
    {
        // 补齐参数，创建Trade
        $tradeType = TRADE_REWARD;
        $tradeConfig = Config::get("trade.trades.$tradeType", []);
        $tradeTypeClass = $tradeConfig['className'] ?? '';

        $rewardId = $params['rewardId'] ?? null;
        $consultingId = $params['consultingId'] ?? null;

        // 渠道链路
        ['pf' => $pf, 'chain' => $chain, 'promotionGroupId' => $promotionGroupId] = getChainParams();

        // 悬赏
        $reward = ConsultingReward::where('id', $rewardId)->find();
        if (!$reward) {
            throw new ValidateException('该悬赏不存在，或已被删除');
        }

        // 咨询
        $consulting = Consulting::where('id', $consultingId)
            ->find();
        if (!$consulting) {
            throw new ValidateException('该咨询不存在，或已被删除');
        }
        if ($consulting->memberId != $user->id) {
            throw new ValidateException('您不能为他人购买服务');
        }
        if ($consulting->isEnd == 1) {
            throw new ValidateException('该咨询已完成，如需悬赏请重新发起');
        }

        $describe = $tradeConfig['name'] . $reward->name;
        $questionId = $consulting->questionId;

        // 暂时没说优惠卷
        $showMoney = $reward->price;
        $totalMoney = $reward->price;
        $payMoney = $totalMoney;
        $settleStatus = Trade::UNSETTLED;

        if ($payMoney < 0.01) {
            throw new ValidateException('订单价格应该大于0');
        }

        $tradeParams = [
            'memberId' => $user->id,
            'orderNoPre' => 'RW',
            'describe' => $describe,
            'tradeType' => $tradeType,
            'tradeTypeClass' => $tradeTypeClass,
            'questionId' => $questionId,
            'consultingId' => $consultingId,
            'rewardId' => $reward->id,
            'showMoney' => $showMoney,
            'totalMoney' => $totalMoney,
            'payMoney' => $payMoney,
            'payStatus' => Trade::UNPAID,
            'payExpTime' => time() + 3600,
            'settleStatus' => $settleStatus,
            'pf' => $pf,
            'chain' => $chain,
            'promotionGroupId' => $promotionGroupId,
            'attach' => [
                'attach' => '',
            ],
        ];

        $record = $this->tradeDao->insertTrade($tradeParams);

        // 触发订单创建事件
        event('TradeCreated', $record);

        return $record;
    }

    // 完成订单
    public function completionTrade(Trade $trade)
    {
        // 购买悬赏成功

        // 咨询
        $consulting = Consulting::where('id', $trade->consultingId)->find();

        // 悬赏
        $reward = ConsultingReward::where('id', $trade->rewardId)->find();

        if (!$consulting || !$reward) {
            // TODO 添加错误日志

            return;
        }

        $now = time();

        // 预估律师佣金
        $lawyerMoney = $this->estimateLawyerMoney($trade->payMoney, $trade->settleStatus, $reward);

        $trade->lawyerMoney = $lawyerMoney;

        // 订单记录服务生效时间
        $trade->startTime = $now;
        $trade->save();

        // 延时触发服务完成任务
        $job_data = ['id' => $trade->id];
        Queue::later(86400, TradeEnd::class, $job_data);

        // 更新活动时间
        $consulting->updateActiveTime(time() + 24 * 3600);

        // 给对应的咨询添加聊天时长和次数
        if ($reward->questionsNum > 0) {

            $questionsNum = $consulting->questionsNum + $reward->questionsNum;

            $consulting->questionsNum = $questionsNum;
            $consulting->questionsNumRemind = 0;
            $consulting->save();
        }

        // 保存预估律师佣金
        $consulting->lawyerMoney = bcadd($consulting->lawyerMoney, $lawyerMoney, 2);
        $consulting->save();

        // 用户消息
        if ($reward->questionsNum > 0) {
            $content1 = [
                'templates' => [
                    ['type' => 'text', 'red' => '102', 'text' => '咨询人数较多，律师利用空闲时间解答，非常不易，感谢您的悬赏。',],
                ],
            ];
            $this->getMessageSendService()->sendSystemMessage($consulting, $consulting->memberId, ConsultingMessage::SYSTEM, $content1);
        }

        // 咨询变动事件
        event('ConsultingUpdated', $consulting);

        // 如果咨询还没有分配律师并且已经提问，那么立即分配一个
        if (!is_id($consulting->lawyerId) && $consulting->matchType == Consulting::MATCH_TYPE_RANDOM && $consulting->isAsked == 1) {

            // 百分比卡片
            $content = [
                'text' => '正在为您优先匹配金牌律师，请稍等....'
            ];
            $this->getMessageSendService()->sendRobotMessage($consulting, null, 0, ConsultingMessage::TEXT, $content);

            // 立即随机分配一个律师
            $this->getConsultingLawyerMatchService()->matchRand($consulting);

        }

        // 激活免费服务
        if ($consulting->consultingType == 0 && is_id($consulting->consultingServerId)) {

            // 初始免费服务
            $freeServer = ConsultingServer::where('id', $consulting->consultingServerId)
                ->where('serverType', ConsultingServer::FREE)
                ->find();

            if ($freeServer) {
                // 免费服务生效
                event('FreeConsultingServerStart', ['consulting' => $consulting, 'server' => $freeServer]);
            }
        }

        // 短信通知律师，用户付费
        if (is_id($consulting->lawyerId)) {
            $phone = Member::where('id', $consulting->lawyerId)->value('phone');
            if (CheckUtil::isPhoneNumber($phone)) {
                $this->getTemplateSmsService()->memberPay($phone, '悬赏', $trade->payMoney);
            }
        }
    }

    // 完成退款，收回服务
    public function completionRefundTrade(Trade $trade)
    {
        // 红包退款成功

        // 咨询
        $consulting = Consulting::where('id', $trade->consultingId)->find();

        // 悬赏
        $reward = ConsultingReward::where('id', $trade->rewardId)->find();

        if (!$consulting || !$reward) {
            // TODO 添加错误日志

            return;
        }

        // 给对应的咨询添加聊天时长和次数
        if ($reward->questionsNum > 0) {

            $questionsNum = $consulting->questionsNum - $reward->questionsNum;
            if ($questionsNum < 0) {
                $questionsNum = 0;
            }

            $consulting->questionsNum = $questionsNum;
            $consulting->save();

            // 给用户消息
            $content = [
                'templates' => [
                    ['type' => 'text', 'red' => '102', 'text' => '退款成功，当前可用聊天次数为：',],
                    ['type' => 'text', 'red' => '101', 'text' => $questionsNum . '次',]
                ],
            ];
            $this->getMessageSendService()->sendSystemMessage($consulting, $consulting->memberId, ConsultingMessage::SYSTEM, $content);

        }

        // 退款消息
        $content = [
            'templates' => [
                ['type' => 'text', 'red' => '102', 'text' => '悬赏退款成功，您发送的',],
                ['type' => 'text', 'red' => '101', 'text' => $reward->name,],
                ['type' => 'text', 'red' => '102', 'text' => '悬赏已原路退回',],
            ],
        ];
        $this->getMessageSendService()->sendSystemMessage($consulting, $consulting->memberId, ConsultingMessage::SYSTEM, $content);

        // 退款消息
        $content = [
            'templates' => [
                ['type' => 'text', 'red' => '102', 'text' => '悬赏退款成功，您接收的',],
                ['type' => 'text', 'red' => '101', 'text' => $reward->name,],
                ['type' => 'text', 'red' => '102', 'text' => '悬赏已原路退回',],
            ],
        ];
        $this->getMessageSendService()->sendSystemMessage($consulting, $consulting->lawyerId, ConsultingMessage::SYSTEM, $content);

        // 咨询扣除预估律师佣金
        $consulting->lawyerMoney -= $trade->lawyerMoney;
        if($consulting->lawyerMoney < 0){
            $consulting->lawyerMoney = 0;
        }
        $consulting->save();

        // 咨询变动事件
        event('ConsultingUpdated', $consulting);

    }

    public function canceledTrade(Trade $trade)
    {
        return;
    }

    private function getMessageSendService(): MessageSendService
    {
        return app(MessageSendService::class);
    }

    private function getTemplateSmsService(): TemplateSmsService
    {
        return app(TemplateSmsService::class);
    }

    private function getConsultingLawyerMatchService(): ConsultingLawyerMatchService
    {
        return app(ConsultingLawyerMatchService::class);
    }

}
